package org.example;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;

@Aspect //告诉框架这是一个切面类
public class qiemian {
    //public void必须的
    @Before(value = "execution(public void org.example.mubiaolei.fangfa1())")  //时间和位置，@Before表示增加的功能出现在目标方法的前面，属性value切点表达式只要参数类型
    public void zengjiafangfa1(){
        System.out.println("增加方法1执行了");
    }
    @Before(value = "execution(* *(..))")
    public void zengjiafangfa2(JoinPoint xy){  //这个参数可以获取到目标类方法的名字和参数等
        Object shuzu1=xy.getArgs();//拿到参数返回object数组，遍历
        xy.getSignature();//获取整个方法的全名
        xy.getSignature().getName();//整个方法的全名之名字
        System.out.println("增加方法2执行了");
    }
@AfterReturning(value = "execution(* *(..))",returning = "xy")//这是后置注释，比较麻烦要求增强的方法必须有参数，用于接收
//目标方法的返回值，Object最好，而且这个参数的变量名字必须和注解的第二个参数值一样
    public void zengjiafangfa3(JoinPoint xy1,Object xy){  //也可以加joinpoint必须是第一个参数
        //这个xy就是接收到的返回值，这里可以重新给它赋值，或者做ifeques判断来做其他事
        System.out.println("增加方法3后置执行了");
    }
@Around(value = "execution(* *(..))")//环绕通知，在目标方法的上下都可以增加方法功能，比较灵活
//该方法必备参数ProceedingJoinPoint类似于jdk动态代理的InvocationHandler接口的invoke方法，XYZ相当于method
//其他的前置后置通知增强只是xml的动态代理对象找到如 @Before这种标志，在目标类方法前后给它加上这个代码，而这里是把目标类的方法整体拿到
//这个方法里面来放着自己管理，然后后台的测试类调用目标类方法时必须绕一圈，在我这个方法里面执行这个目标类方法，当然我这个类可以控制目标类
//方法执不执行和灵活的前后增加功能还有控制和改变你目标方法的执行结果
//ProceedingJoinPoint已经包含了JoinPoint的功能，下面重复了
    public Object zengjiafangfa4(JoinPoint xy1, ProceedingJoinPoint xyz) throws Throwable {  //该方法必须有返回值，相当于后台的测试类
        //调用了这个方法执行里面的目标类的方法，必须经过这个类，所以这个类可以控制改变目标方法执行结果，返回给测试类时就给他改变了
    Object fanhuizhi=null;
        System.out.println("增加方法4环绕上执行了");
    fanhuizhi=xyz.proceed();//这个方法启用，才能启用从目标类拿过来的方法，所以灵活控制前后加不加，还可以控制目标方法执行不执行
        System.out.println("增加方法4环绕下执行了");
        return  fanhuizhi;
    }
    @Pointcut(value = "execution(* *(..))")//一个切面类中多处用同一个切入点，就取别名，然后在切入点表达式就用这个方法名代表原来切入点名
    private  void bieming(){}//切入点别名感觉没啥用

}
